package com.example.base;

import com.example.util.annotation.invisiable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;

/**
 * @功能说明：spring上下文持有工具类
 */
@Component
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {

    private static ApplicationContext applicationContext = null;

    private static final Log LOGGER = LogFactory.getLog(SpringContextHolder.class);

    /**
     * 实现ApplicationContextAware接口, 注入Context到静态变量中.
     */
    public void setApplicationContext(ApplicationContext applicationContext) {

        LOGGER.debug("注入ApplicationContext到SpringContextHolder:" + applicationContext);

        SpringContextHolder.applicationContext = applicationContext; // NOSONAR
    }

    /**
     * 实现DisposableBean接口,在Context关闭时清理静态变量
     */
    public void destroy() throws Exception {

        SpringContextHolder.clear();
    }

    /**
     * 取得存储在静态变量中的ApplicationContext.
     */
    public static ApplicationContext getApplicationContext() {

        assertContextInjected();
        return applicationContext;
    }

    /**
     * 从静态变量applicationContext中取得Bean, 自动转型
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {

        assertContextInjected();
        return (T) applicationContext.getBean(name);
    }
    public static <T> T getBean(Class<?> classname) {

        assertContextInjected();
        return (T) applicationContext.getBean(classname);
    }
    /**
     * 清除SpringContextHolder中的ApplicationContext为Null.
     */
    public static void clear() {

        LOGGER.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
        applicationContext = null;
    }

    private static void assertContextInjected() {

        if (applicationContext == null) {
            throw new IllegalStateException("applicaitonContext未注!请在applicationContext.xml中定义SpringContextHolder");
        }
    }
    public static void  visiablePropertys( Class<?> clazz,List<String> propertys)
    {
        if(clazz.getSuperclass() !=Object.class)
            visiablePropertys( clazz.getSuperclass() ,propertys);
        Field[] fields=clazz.getDeclaredFields();

        for(Field item:fields)
        {
            invisiable[] annotation = item.getAnnotationsByType(invisiable.class);
            if((annotation==null||annotation.length==0)&&(!Modifier.isStatic(item.getModifiers())))
            {
                propertys.add(item.getName());
            }
        }

    }

}
